<?php
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Event;
use App\Services\UserService;
use Illuminate\Support\Facades\Response as FacadesResponse;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Session;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;





/**
 * 这个Controller显示主页面
 *
 * @author hongyang
 */
class HomeController extends BaseController
{

	protected $layout = 'layouts.master';

	/**
	 * @var Weixinhelper
	 */
	protected $iWeixin;
	protected $userService;

	public function __construct(UserService $userService)
	{
		$this->userService = $userService;
		$this->iWeixin = new WeixinHelper();
		parent::__construct();
	}
	
	public function getRegCode()
	{
											
		$str = rand(1000,9999);		
        Session::put('reg_code',$str);

        //验证码图片的宽度
        $width  = 50;

        //验证码图片的高度
        $height = 20;

        //声明需要创建的图层的图片格式
        header('Content-type: image/jpeg');

        //创建一个图层
        $im = imagecreate($width, $height);

        //背景色
        $back = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);

        //模糊点颜色
        $pix  = imagecolorallocate($im, 187, 230, 247);

        //字体色
        $font = imagecolorallocate($im, 41, 163, 238);

        //绘模糊作用的点
        mt_srand();
        for ($i = 0; $i < 1000; $i++) {
            imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $pix);
        }

        //输出字符
        imagestring($im, 5, 7, 5, $str, $font);

        //输出矩形
    //    imagerectangle($im, 0, 0, $width -1, $height -1, $font);

        //输出图片
        imagepng($im);

        imagedestroy($im);

        //$mime_type = mime_content_type($uploadfile);
        return Response::make('', 200, ['content-type' => 'image/jpeg']);
              
	}
	
	public function index()
	{
		$this->layout->content = View::make('home.index');
	}

	public function loginWithQq()
	{
		$this->layout->content = View::make('errors.coming');
	}

	public function loginview()
	{
		$this->layout->content = View::make('home.login');
	}
	
	/**
	 * 用户登陆
	 */
	public function login()
	{
		if (Input::server('REQUEST_METHOD') == 'POST') {
			$wx_openid = Input::get('wx_openid', null);
			$username = Input::get('username');
			if (preg_match("/^1[3-8]\d{9}$/", $username)) {
				$account_type = 'phone';
			} else {
				$account_type = 'email';
			}
			$credentials = [
				$account_type => $username,
				'password'    => Input::get('password'),
			];
			$remember = Input::get('remember') ? true : false;
			if (Auth::attempt($credentials, $remember)) {
				$redirect_url = $this->getLoginRedirectUrl();
				$token = $this->userService->getNewToken();
				$response = FacadesResponse::json([
					"status_code"      => 302,
					"success_messages" => ["用户已经成功登录。"],
					"data"             => $this->userService->getAuthUserData(),
					"token"            => $token,
					"redirect_url"     => $redirect_url,
				], 200, ["Authorization" => "bearer " . $token]);
				//注册成功事件
				Event::fire('register_login_event', [Auth::user(), Input::all()]);

				/**
				 * 存储wx_openid
				 */
				if($wx_openid){
					Auth::user()->wx_openid = $wx_openid;
					Auth::user()->save();
				}
				return $response;
			} else {				
				$user = DB::table('user')->where('account',$username)->first();							        
				if(password_verify(Input::get('password'),$user->password)){			
						Auth::loginUsingId($user->id);
						$redirect_url = $this->getLoginRedirectUrl();
						$token 				= $this->userService->getNewToken();
						$response 		= FacadesResponse::json([
								"status_code"      => 302,
								"success_messages" => ["用户已经成功登录。"],
								"data"             => $this->userService->getAuthUserData(),
								"token"            => $token,
								"redirect_url"     => $redirect_url,
						], 200, ["Authorization" => "bearer " . $token]);
						//注册成功事件
						Event::fire('register_login_event', [Auth::user(), Input::all()]);

						/**
						 * 存储wx_openid
						*/
						if($wx_openid){
							Auth::user()->wx_openid = $wx_openid;
							Auth::user()->save();
						}
						return $response;
				}				        
        				
				// 登录失败
				return FacadesResponse::json([
					"status_code"    => 400,
					'error_messages' => [
						'password' => ['账号或密码错误，请重新登录。'],
					],
				], 400);
			}
		} else {
			// wechat login
			$wxHelper = new WeixinHelper();
			$wxloginUrl = $wxHelper->getUrl();

			// qq login


			$this->layout->content = View::make('home.login', ['wxloginUrl' => $wxloginUrl]);
			
		}
	}

	/**
	 * 绑定用户的手机号
	 *
	 * 通过微信的unionid找到用户
	 * - 如果手机没有对应的帐号，则直接绑定手机
	 * - 如果手机有对应的帐号，那看看手机是否已经有绑定的微信号
	 *   - 如果有的话就返回错误
	 *   - 如果没有的话就直接把两个openid和手机对应的两个账号绑定起来
	 */
	public function bindWithPhone()
	{
		// validate openid and phone number
		$post = Input::all();
		// mobile
		Validator::extend('phone', function ($attr, $value, $parameters) {
			return preg_match("/^1[3-8]\d{9}$/", $value);
		});

		Validator::extend('phonecode', function ($attr, $value, $parameters) {
			$phone = Activation::where('token', $value)->where('expired', '>', time())->pluck('mobile');
			if ($phone) {
				return Input::get('phone') == $phone;
			} else {
				return false;
			}
		});

		$rules['phone'] = 'required|phone';
		$messages['phone.required'] = '手机验证码没有填写';
		$messages['phone.phone'] = '手机号格式不正确';
		// $rules['phonecode'] = 'required|phonecode';
		// $messages['phonecode.required']='手机验证码没有填写';
		// $messages['phonecode.phonecode'] = '手机验证码错误';
		$rules['union_id'] = 'required';
		$messages['union_id.required'] = 'union_id没有填写';


		$rules['platform'] = 'required';
		$messages['platform.required'] = 'platform没有填写';


		$validator = Validator::make($post, $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return FacadesResponse::json([
				"status_code"    => 400,
				'error_messages' => $validator->errors(),
			], 400);
		}

		// 通过了validations

		// 通过手机找对应的帐号
		$bindingUser = null;
		try {
			$bindingUser = User::getByUsername($post['phone']);
		} catch (Exception $ex) {
			Log::info(sprintf("User account with phone number: %s is not found.", $post['phone']));
		}

		// 1. 如果手机没有对应的帐号，则直接创建一个新的用户并且绑定手机和union_id
		if (!$bindingUser) {
			$user = User::addUserWithWxUnionId($post, $post['platform']);
			$user->phone = $post['phone'];
			$user->account = $post['phone'];
			$user->save();
		} else {
			// 2. 如果手机有对应的帐号，那看看手机是否已经有绑定的微信号，如果有的话就返回错误
			$column = $post['platform'] == 'wx' ? 'union_id' : 'qq_openid';
			if ($bindingUser->$column) {
				return FacadesResponse::json([
					"status_code"    => 400,
					'error_messages' => '这个手机对应的用户已经有绑定的'.$column.'了',
				], 400);
			} else {
				// 3. 如果手机有对应的帐号，那看看手机是否已经有绑定的微信号，如果没有的话就直接把两个openid和手机对应的两个账号绑定起来
				$bindingUser->$column = $post['union_id'];
				$bindingUser->save();
				$user = $bindingUser;
			}
		}

		// 登录用户，然后返回用户数据和token
		if(isset($post['wx_openid'])){
			$user->wx_openid = $post['wx_openid'];
			$user->save();
		}
		Auth::login($user);
		Event::fire('register_login_event', [$user, Input::all()]);
		$token = $this->userService->getNewToken();
		$response = FacadesResponse::json([
			"status_code"      => 200,
			"success_messages" => ["用户已经成功登录。"],
			"data"             => $this->userService->getAuthUserData(),
			"token"            => $token,
		], 200, ["Authorization" => "bearer " . $token]);

		return $response;
	}

	public function loginWithWx()
	{

		// validate code and state
		$rules['wx_openid'] = 'required';
		$messages['wx_openid'] = 'wx_openid是必须的';

		$validator = Validator::make(Input::all(), $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return FacadesResponse::json([
				"status_code"    => 400,
				'error_messages' => $validator->errors(),
			], 400);
		}

		$openid = Input::get('wx_openid');

		Session::set('wx_openid', $openid);

		$this->loginWithWeixinID($openid);

		Event::fire('register_login_event', [Auth::user(), Input::all()]);

		$redirect_url = $this->getLoginRedirectUrl();

		$token = $this->userService->getNewToken();
		$response = FacadesResponse::json([
			"status_code"      => 200,
			"success_messages" => ["用户已经成功登录。"],
			"data"             => $this->userService->getAuthUserData(),
			"token"            => $token,
			"redirect_url"     => $redirect_url,
		], 200, ["Authorization" => "bearer " . $token]);

		return $response;
	}

	/**
	 * 把用户的用户名和他微信的openid进行绑定
	 */
	public function bindUserWithOpenId()
	{

		// validate code and state
		$rules['open_id'] = 'required';
		$messages['open_id'] = 'openid是必须的';

		$validator = Validator::make(Input::all(), $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return FacadesResponse::json([
				"status_code"    => 400,
				"error_messages" => $validator->errors(),
			], 400);
		}

		$openid = Input::get('open_id');

		try {
			$user = Auth::user();
			$user->wx_openid = $openid;
			$user->save();
		} catch (Exception $ex) {
			return FacadesResponse::json([
				"status_code"    => 400,
				"error_messages" => "the username is not found",
			], 400);
		}

		$response = FacadesResponse::json([
			"status_code" => 200,
		], 200);

		return $response;
	}

	/**
	 * 刷新登录的token
	 */
	public function refreshToken()
	{
		$token = JWTAuth::getToken();
		if (!$token) {
			return $this->makeView('errors.400', 'token not provided', 400);
		}

		try {
			$token = JWTAuth::refresh($token);
		} catch (TokenInvalidException $e) {
			Log::error($e);

			return FacadesResponse::json([
				"status_code"    => 400,
				'error_messages' => 'this token is invalid',
			], 400);
		}

		$user = JWTAuth::toUser($token);

		DB::table('user')->where('id', '=', $user->id)->update([
			'login_token' => $token,
		]);

		return $this->makeView('general.200', ['token' => $token], 200);
	}

	public function obtainOpenId()
	{
		// validate code and state
		$rules['state'] = 'required';
		$rules['code'] = 'required';
		$messages['state'] = 'state是必须的';
		$messages['code'] = 'code是必须的';

		$validator = Validator::make(Input::all(), $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return FacadesResponse::json([
				"status_code"    => 400,
				'error_messages' => $validator->errors(),
			], 400);
		}

		$code = Input::get('code');
		$state = Input::get('state');
		Log::info("$openid==========code=".$code.",state=".$state);

		try {
			$accessInfo = $this->iWeixin->oAuth($code);
		} catch (Exception $ex) {
			Log::error($ex);

			return FacadesResponse::json([
				"status_code"    => 503,
				'error_messages' => [
					'wxlogin' => ["请求失败，请检查参数再试。code=".$code.",state=".$state],
				],
			], 503);
		}
		Log::info("$openid==========accessInfo=".$accessInfo);
		if (isset($accessInfo->errcode)) {
			Log::error($accessInfo);

			return FacadesResponse::json([
				"status_code"    => 503,
				'error_messages' => [
					'wxlogin' => ["请求失败，请稍后再试。"],
				],
			], 503);
		}

		$access_token = $accessInfo->access_token;
		$openid = $accessInfo->openid;
		Log::info("$openid===========".$openid.",code=".$code);
		$data = ['wx_openid' => $openid, 'access_token' => $access_token];
		if (isset($accessInfo->unionid)) {
			$data['unionid'] = $accessInfo->unionid;
		}

		Session::set('wx_openid', $openid);

		$response = FacadesResponse::json([
			"status_code"      => 200,
			"success_messages" => ["已经成功获取第三方咨询。"],
			"data"             => $data,
		], 200);

		return $response;
	}

	public function loginWithWeixinID($openid)
	{
		if (Auth::guest()) {
			$user = User::where('wx_openid', $openid)->first();
			if (!$user) {
				$user = User::addUserWithWxUnionId(['union_id' => $openid], 'wx');
			}
			Auth::login($user);
		} else {
			$user = Auth::user();
			if (!$user->wx_openid) {
				$user->wx_openid = $openid;
				$user->save();
			}
		}
		//注册成功事件
		Event::fire('register_login_event', [Auth::user(), Input::all()]);
	}


	protected function getLoginRedirectUrl()
	{
		$user = Auth::user();

		// 登录成功
		$backurl = Input::get('backurl');
		if ($user->active == 1) {
			$redirect_url = URL::route('home.index');

			if ($backurl) {
				$redirect_url = $backurl;
			} elseif ($user->user_group_id == 2) {
				$redirect_url = URL::route('center.lawyer.main');
			}
		} else {
			$parameters = [
				'account_type' => 'phone',
			];
			if ($backurl) {
				$parameters['backurl'] = $backurl;
			}
			$redirect_url = URL::route('center.welcome', $parameters);
		}

		return $redirect_url;
	}

	/**
	 * 用户注册
	 *
	 * @param number $uid
	 *
	 * todos
	 * - what is refer?
	 * - validate phone code
	 * - uid is the invitor's id
	 */
	public function register($uid = 0)
	{

		if (Input::server('REQUEST_METHOD') == 'POST') {
// 			if ($uid == 0 ){
// 				$uid = Session::get('from_uid');
// 			}

			// Validation
			
			
			$rules = [
				'password' => 'required|between:6,18',
			];
			$messages = [
				'password.required' => '请填写密码',
				'password.between'  => '密码长度在:min到:max之间',
			];

			$post = Input::all();
			$account_type = $post ['account_type'];
			if ($account_type == 'phone') {
				// mobile
				Validator::extend('username', function ($attr, $value, $parameters) {
					return preg_match("/^1[3-8]\d{9}$/", $value);
				});

				Validator::extend('phonecode', function ($attr, $value, $parameters) {
					$phone = Activation::where('token', $value)->where('expired', '>', time())->pluck('mobile');
					if ($phone) {
						return Input::get('username') == $phone;
					} else {
						return false;
					}
				});

				$rules['username'] = 'username|unique:user,phone';
				$messages['username.username'] = '手机号格式不正确';
				$messages['username.unique'] = '这个手机号已经注册了';
				$rules['phonecode'] = 'required|phonecode';
				$messages['phonecode.required'] = '手机验证码没有填写';
				$messages['phonecode.phonecode'] = '手机验证码错误';
			} else {
				// validate the CAPTCHA
				if (!isset($post ['client']) || $post['client'] != 'mobile') {
					Validator::extend('captcha', function ($attr, $value, $parameters) {
						return CaptchaHelper::verify($value);
					});
					$rules['emailcode'] = 'captcha';
					$messages['emailcode.captcha'] = '验证码错误';
				}

				// email
				$rules['username'] = 'required|unique:user,email|email';
				$messages['username.required'] = '请输入邮箱';
				$messages['username.unique'] = '这个邮箱已经注册了';
				$messages['username.email'] = '邮箱格式不正确';
			}

			$validator = Validator::make($post, $rules, $messages);
			if ($validator->fails()) {
				// the given data did not pass validation
				return FacadesResponse::json([
					"status_code"    => 400,
					'error_messages' => $validator->errors(),
				], 400);
			}

			// Validation成功
			try {
				$active = ($post ['account_type'] == 'phone') ? 1 : 0;
				$user = User::addUser($post ['username'], $post ['password'], $post ['account_type'], $active);
				if (isset($post['wx_openid'])) {
					$user->wx_openid = $post['wx_openid'];
					$user->save();
				}
				if (isset($post['union_id'])) {
					$user->union_id = $post['union_id'];
					$user->save();
				}

				$users = [
					'username' => $user->id,
					'password' => $user->password,
					'nikname'  => '匿名',
				];
				$result = new Easemob();
				$result_re = $result->accreditRegister([$users]);
			} catch (Exception $ex) {
				// $user->delete();
				Log::error($ex);

				return FacadesResponse::json([
					"status_code"    => 503,
					'error_messages' => [
						'register' => ['账户注册失败，请稍后再试。'],
					],
				], 503);
			}

			if ($post ['account_type'] == 'phone') {
				UserScoresHistory::registration($user);
				StationLetter::sendWelcomeLetter($user);

				Auth::login($user);
				$redirect_url = URL::route('center.welcome', ['account_type' => $account_type]);

				$token = $this->userService->getNewToken();
				$response = FacadesResponse::json([
					"status_code"  => 302,
					"data"         => $this->userService->getAuthUserData(),
					"token"        => $token,
					'redirect_url' => $redirect_url,
				], 200, ["Authorization" => "bearer " . $token]);

				return $response;
			}

			if ($post ['account_type'] == 'email') {
				$activation = Activation::firstOrNew([
					'email' => $user->email,
				]);
				$activation->token = str_random(40);
				$activation->expired = time() + 86400 * 7;
				$activation->save();
				Mail::send('emails.auth.activation', [
					'token' => $activation->token,
				], function ($message) use ($user) {
					$message->to($user->email)->subject('注册验证成功');
				});

				// 注册成功
				Auth::login($user);
				$redirect_url = URL::route('center.welcome', ['account_type' => 'email']);
				$token = $this->userService->getNewToken();
				$response = FacadesResponse::json([
					"status_code"      => 302,
					"data"             => $this->userService->getAuthUserData(),
					"token"            => $token,
					"success_messages" => ["用户已经成功注册。"],
					"redirect_url"     => $redirect_url,
				], 200, ["Authorization" => "bearer " . $token]);
				//注册成功事件
				Event::fire('register_login_event', [$user, Input::all()]);

				return $response;
			}

// 			if (Session::get ( 'wx_openid' )) {
// 				$user->wx_openid = Session::get ( 'wx_openid' );
// 			}
		} else {
			$this->layout->content = View::make('home.register');
		}
	}



	/**
	 * 发送手机验证码
	 *
	 * @return string
	 */
	public function sendCode()
	{
		
		
		$posts = Input::all();
		$rules = [
			'phone' => ['required', 'regex:/^1[3-8]\d{9}$/i'],
		];
		$messages = [
			'phone.required' => '该手机号格是需要的',
			'phone.regex'    => '该手机号格式错误',
		];

		$phone = $posts['phone'];
		if (!isset($posts['uncheck'])) {
			$code  = $posts['code'];
			$chk_code =  Session::get('reg_code',"");
		        if($code != $chk_code){			
				return $this->makeView('errors.400', ['phone' => ['图形验证码不正确']], 400);
			}
		}
		$requestTimeArr = Session::get($phone);
		if (is_array($requestTimeArr)) {
			foreach ($requestTimeArr as $key => $value) {
				$times = time() - $requestTimeArr[$key];
				if ($times > 3600) {
					Session::forget($phone . '.' . $key);
				}
			}
			if (count($requestTimeArr) >= 3) {
				return $this->makeView('errors.400', ['phone' => ['一小时内只能获取三次验证码']], 400);
			} else {
				Session::push($phone, time());
			}
		} else {
			Session::push($phone, time());
		}
		$validator = Validator::make($posts, $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return $this->makeView('errors.400', $validator->errors(), 400);
		} else {
			$activation = Activation::firstOrNew([
				'mobile' => $phone,
			]);

			$activation->token = UtilsHelper::generateRandomNumbers(5);
			$activation->expired = time() + 3600;
			$activation->save();
			try {
				//短信文案
				MsgHelper::sendSMS($phone, sprintf("【律团网】欢迎注册律团网，您的验证码为%s,请尽快进行验证（一小时内有效），并勿向其他人泄露您的验证码。", $activation->token));
			} catch (Exception $ex) {
				Log::error($ex);

				return $this->makeView('errors.503', '获取验证码失败，请稍后再试。', 503);
			}

			return FacadesResponse::json([
				"status_code"      => 200,
				'success_messages' => '验证码已发送到您的手机',
			], 200);
		}
	}

	/**
	 * 激活用户
	 *
	 * @param string $token
	 */
	public function activation($token)
	{
		$len = strlen($token);
		if ($len > 10) {
			$email = Activation::where('token', $token)->where('expired', '>', time())->pluck('email');
			if ($email) {
				$user = User::where('email', $email)->first();
				if (!$user->active) {
					$user->active = 1;
					$user->save();

					UserScoresHistory::registration($user);
					StationLetter::sendWelcomeLetter($user);
				}
				Auth::login($user);

				return Redirect::route('center.customer.info');
			}
		} elseif ($len > 0) {
			$phone = Activation::where('token', $token)->where('expired', '>', time())->pluck('mobile');
			if ($phone) {
				$user = User::where('phone', $phone)->first();
				if (!$user->active) {
					$user->active = 1;
					$user->save();
				}

				return Redirect::route('center.customer.info');
			}
		}
	}

	/**
	 * 注销用户
	 */
	public function logout()
	{
		Easemob::removeTokenFromSession();
		Auth::logout();
		switch (Config::get('response.content_type')) {
			case 'application/json':
				return FacadesResponse::view("general.200_json", ['data' => '成功注销'])->header('Content-Type', 'application/json')->setStatusCode(200);
				break;
			case 'text/html':
			default:
				return Redirect::route('home.index');
		}

	}

	/**
	 * 绑定手机号
	 */
	public function BindPhone()
	{
		return $this->makeView('home.bind_phone');
	}

	/**
	 * 微信登录请求
	 */
	public function LoginJson()
	{
		return $this->makeView('home.login_json');
	}

	/**
	 * 返回省份列表
	 */
	public function provinceList()
	{
		$provinces = AreaHelper::getProvinceList();

		return $this->makeView('helper.area', $provinces);
	}

	/**
	 * 返回城市列表
	 */
	public function cityList($provinceId)
	{
		$provinces = AreaHelper::getProvinceList();
		if (!AreaHelper::areaKeyExists($provinceId, $provinces)) {
			return FacadesResponse::json([
				"status_code" => 404,
			], 404);
		}
		$cities = AreaHelper::getCityList($provinceId);

		return $this->makeView('helper.area', $cities);
	}

	/**
	 * 返回区域列表
	 */
	public function districtList($cityId)
	{
		$provinceId = substr($cityId, 0, 2) . '0000';
		$provinces = AreaHelper::getProvinceList();
		$cities = AreaHelper::getCityList($provinceId);
		if (!AreaHelper::areaKeyExists($provinceId, $provinces) || !AreaHelper::areaKeyExists($cityId, $cities)) {
			return FacadesResponse::json([
				"status_code" => 404,
			], 404);
		}

		$districts = AreaHelper::getDistrictList($cityId);

		return $this->makeView('helper.area', $districts);
	}

	/**
	 * 省份根据首字母排序
	 */
	public function provinceLetters()
	{
		$provinces = AreaHelper::getProvinceLetter();

		return $this->makeView('helper.area', $provinces);

	}

	/**
	 * 通过union_id检查用户是否存在
	 * @param $union_id
	 * @return 如果存在则登录返回token or false
	 */
	public function checkUser()
	{
		$post = Input::all();

		// Validation
		$rules = [
	//		'union_id' => 'required',
			'platform' => 'required',
		];
		
		Log::info(json_encode($post));
		$messages = [
	//		'union_id.required' => '请填写union_id'.json_encode($post),
			'platform.required' => '请填写platform'
		];


		$validator = Validator::make($post, $rules, $messages);
		if ($validator->fails()) {
			// the given data did not pass validation
			return FacadesResponse::json([
				"status_code"    => 400,
				'error_messages' => $validator->errors(),
			], 400);
		}

		return $this->userService->checkUser($post);
	}
}
